/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.treeeditpart;

import org.eclipse.gef.EditPartViewer;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.PlatformUI;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Interaction;
import org.eclipse.uml2.uml.NamedElement;

import com.cea.papyrus.core.IPapyrusUIConstants;
import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.helper.IModelerHelper;
import com.cea.papyrus.core.helper.ModelerHelper;
import com.cea.papyrus.diagraminterchange2.di2.Di2Factory;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

/**
 * 
 */
public class CreateElementAction extends Action {

    /**
     * 
     */
    private EditPartViewer viewer;

    /**
     * 
     */
    private Class elementClass;

    /**
     * 
     */
    protected ModelManager modelManager;

    /**
     * 
     */
    protected String type;

    /**
     * To create an elemnt from the viewer.
     * 
     * @param viewer
     * @param modelManager
     * @param elementClass
     *            to create
     * @param type
     */
    public CreateElementAction(EditPartViewer viewer, Class elementClass, ModelManager modelManager, String type) {
        this.viewer = viewer;
        this.modelManager = modelManager;
        this.type = type;

        int indexPoint = elementClass.getName().lastIndexOf('.') + 1;
        this.setText("" + elementClass.getName().substring(indexPoint).toLowerCase());
        this.setToolTipText("" + elementClass.getName().substring(indexPoint).toLowerCase());
        this.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(org.eclipse.ui.ISharedImages.IMG_TOOL_NEW_WIZARD));
        this.elementClass = elementClass;

        // UMLObjectLabelProvider imageProvider = new UMLObjectLabelProvider();
        // no need to create a imageprovider
        Image img = PapyrusPlugin.UML_LABEL_PROVIDER.getImage(elementClass, type);
        this.setImageDescriptor(ImageDescriptor.createFromImage(img));
    }

    /**
     * run the creation of the element.
     */

    @Override
    public void run() {
        ISelection selection = viewer.getSelection();
        Object e = ((IStructuredSelection) selection).getFirstElement();
        Element umlElement = ((ElementTreeEditPart) e).getUmlElement();
        // showMessage("create Element Action");
        if (elementClass.equals(Diagram.class)) {
            // diagram
            if ((type == null) || type.equals(IPapyrusUIConstants.CLASS_DIAGRAM)) {
                modelManager.createDiagram(umlElement, "Class diagram of "
                        + ((NamedElement) umlElement).getName(), IPapyrusUIConstants.CLASS_DIAGRAM);
            } else if (type.equals(IPapyrusUIConstants.COMPOSITE_STRUCTURE_DIAGRAM)) {
                modelManager.createDiagram(umlElement, "Composite diagram of "
                        + ((NamedElement) umlElement).getName(),
                        IPapyrusUIConstants.COMPOSITE_STRUCTURE_DIAGRAM);
            } else if (type.equals(IPapyrusUIConstants.STATE_MACHINE_DIAGRAM)) {
                modelManager.createDiagram(umlElement, "State Machine diagram of "
                        + ((NamedElement) umlElement).getName(), IPapyrusUIConstants.STATE_MACHINE_DIAGRAM);
            } else if (type.equals(IPapyrusUIConstants.USE_CASE_DIAGRAM)) {
                modelManager.createDiagram(umlElement, "Use Case diagram of "
                        + ((NamedElement) umlElement).getName(), IPapyrusUIConstants.USE_CASE_DIAGRAM);
            } else if (type.equals(IPapyrusUIConstants.DEPLOYMENT_DIAGRAM)) {
                modelManager.createDiagram(umlElement, "Deployment diagram of "
                        + ((NamedElement) umlElement).getName(), IPapyrusUIConstants.DEPLOYMENT_DIAGRAM);
            } else if (type.equals(IPapyrusUIConstants.ACTIVITY_DIAGRAM)) {
                modelManager.createDiagram(umlElement, "Activity diagram of "
                        + ((NamedElement) umlElement).getName(), IPapyrusUIConstants.ACTIVITY_DIAGRAM);
            } else if (type.equals(IPapyrusUIConstants.COMPONENT_DIAGRAM)) {
                modelManager.createDiagram(umlElement, "Component diagram of "
                        + ((NamedElement) umlElement).getName(), IPapyrusUIConstants.COMPONENT_DIAGRAM);
            } else if (type.equals(IPapyrusUIConstants.SEQUENCE_DIAGRAM)) {
                Diagram diagram =
                        modelManager.createDiagram(umlElement, "Sequence diagram of "
                                + ((NamedElement) umlElement).getName(),
                                IPapyrusUIConstants.SEQUENCE_DIAGRAM);
                if (umlElement instanceof Interaction) {
                    Interaction interaction = (Interaction) umlElement;
                    GraphNode graphNode = Di2Factory.eINSTANCE.createGraphNode();
                    Uml1SemanticModelBridge semanticModelBridge =
                            Di2Factory.eINSTANCE.createUml1SemanticModelBridge();
                    semanticModelBridge.setElement(interaction);
                    graphNode.setSemanticModel(semanticModelBridge);
                    diagram.getContained().add(graphNode);
                }
            }
            ((ElementTreeEditPart) e).refresh();

        } else {

            // try to create an element from class diagram factory
//            Element anUmlElement = ClassDiagramModelerHelper.getInstance().createUMLElement(elementClass, umlElement);
            Element anUmlElement = getDiagramModelHelper(IPapyrusUIConstants.CLASS_DIAGRAM).createUMLElement(elementClass, umlElement);
            if (anUmlElement == null) {
                // null! maybe from composite diagramfactory
//                anUmlElement = CompositeModelerHelper.getInstance().createUMLElement(elementClass,  umlElement);
                anUmlElement = getDiagramModelHelper(IPapyrusUIConstants.COMPOSITE_STRUCTURE_DIAGRAM).createUMLElement(elementClass, umlElement);
            }
            if (anUmlElement == null) {
                // null! maybe from UseCase diagramfactory
//                anUmlElement = UseCaseDiagramModelerHelper.getInstance().createUMLElement(elementClass,   umlElement);
                anUmlElement = getDiagramModelHelper(IPapyrusUIConstants.USE_CASE_DIAGRAM).createUMLElement(elementClass, umlElement);
            }
            if (anUmlElement == null) {
                // null! maybe from stateMachine diagramfactory
//                anUmlElement = StateMachineDiagramModelerHelper.getInstance().createUMLElement( elementClass, umlElement);
                anUmlElement = getDiagramModelHelper(IPapyrusUIConstants.STATE_MACHINE_DIAGRAM).createUMLElement(elementClass, umlElement);
            }
            if (anUmlElement == null) {
                // null! maybe from deployment diagramfactory
//                anUmlElement = DeploymentDiagramModelerHelper.getInstance().createUMLElement(elementClass,  umlElement);
                anUmlElement = getDiagramModelHelper(IPapyrusUIConstants.DEPLOYMENT_DIAGRAM).createUMLElement(elementClass, umlElement);
            }
            if (anUmlElement == null) {
                // null! maybe from activity diagramfactory
//                anUmlElement = ActivityDiagramModelerHelper.getInstance().createUMLElement(elementClass, umlElement);
                anUmlElement = getDiagramModelHelper(IPapyrusUIConstants.ACTIVITY_DIAGRAM).createUMLElement(elementClass, umlElement);
            }
            if (anUmlElement == null) {
                // null! maybe from component diagramfactory
//                anUmlElement = ComponentDiagramModelerHelper.getInstance().createUMLElement(elementClass,umlElement);
            	anUmlElement = getDiagramModelHelper(IPapyrusUIConstants.COMPONENT_DIAGRAM).createUMLElement(elementClass, umlElement);
            }
        }
    }

    /**
     * Get a model helper by its type.
     * 
     * @return
     */
    private IModelerHelper getDiagramModelHelper(String type) {      
        return ModelerHelper.getFactory(type);
    }

}
